{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f1 2\n",
      "f2\n",
      "f3\n",
      "<function f1 at 0x000001E91005A7B8>\n"
     ]
    }
   ],
   "source": [
    "def f1():\n",
    "    x=2\n",
    "    print('f1',x)\n",
    "    def f2():\n",
    "        print('f2')\n",
    "        def f3():\n",
    "            print('f3')\n",
    "        f3()\n",
    "    f2()\n",
    "f1()\n",
    "print(f1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f1 2\n",
      "f2\n",
      "f3\n"
     ]
    }
   ],
   "source": [
    "f1()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'f3' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-12-c1cd3a33b4be>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mf3\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'f3' is not defined"
     ]
    }
   ],
   "source": [
    "f3()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<function foo.<locals>.bar at 0x000001E910033B70>\n",
      "False\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x=1\n",
    "def foo(x):\n",
    "    def bar(y):\n",
    "#         x=13   (在调用bar函数时，遵从LEGB)\n",
    "        return x<y\n",
    "    return bar\n",
    "f= foo(10)\n",
    "print(f)\n",
    "print(f(5))\n",
    "print(f(12))\n",
    "print(f(20))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<function foo.<locals>.bar at 0x000001E90DF8A620>\n",
      "False\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x=1\n",
    "def foo(x):\n",
    "    def bar(y):\n",
    "        x=13   #(在调用bar函数时，遵从LEGB顺序查找)\n",
    "        return x<y\n",
    "    return bar\n",
    "f= foo(10)\n",
    "print(f)\n",
    "print(f(5))\n",
    "print(f(12))\n",
    "print(f(20))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "13\n"
     ]
    }
   ],
   "source": [
    "# x=1\n",
    "def ta( ):\n",
    "    num=1\n",
    "    print(num)\n",
    "    def ba ( ):\n",
    "        global num\n",
    "        num=13   #(在调用bar函数时，遵从LEGB顺序查找)\n",
    "        return num\n",
    "    num=10\n",
    "    return ba( )\n",
    "print(ta())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alex的书 P139   解释nonlocal 的代码相当不错"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "P140 的global 和 nonlocal对比也很不错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<function foo.<locals>.bar at 0x000001E91005A1E0>\n",
      "False\n",
      "True\n",
      "True\n",
      "(<cell at 0x000001E90FFB63D8: int object at 0x000000006BC7B200>,)\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "\n",
    "def foo(x):\n",
    "#     x=1\n",
    "    def bar(y):\n",
    "#         x=13   #(在调用bar函数时，遵从LEGB顺序查找)\n",
    "#         print(x)\n",
    "        return x<y\n",
    "    return bar\n",
    "f= foo(10)\n",
    "print(f)\n",
    "print(f(5))\n",
    "print(f(12))\n",
    "print(f(20))\n",
    "print(f.__closure__)\n",
    "print(f.__closure__[0].cell_contents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<function foo.<locals>.bar at 0x000001E910033B70>\n",
      "5\n",
      "12\n",
      "20\n",
      "None\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "'NoneType' object is not subscriptable",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-36-e6c05273cd4f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__closure__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 14\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__closure__\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcell_contents\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'NoneType' object is not subscriptable"
     ]
    }
   ],
   "source": [
    "def foo(x):\n",
    "#     x=1\n",
    "    def bar(y):\n",
    "#         x=13   #(在调用bar函数时，遵从LEGB顺序查找)\n",
    "#         print(x)\n",
    "        return y\n",
    "    return bar\n",
    "f= foo(10)\n",
    "print(f)\n",
    "print(f(5))\n",
    "print(f(12))\n",
    "print(f(20))\n",
    "print(f.__closure__)\n",
    "print(f.__closure__[0].cell_contents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.014845132827759\n"
     ]
    }
   ],
   "source": [
    "import time \n",
    "def func():\n",
    "    start=time.time()\n",
    "    time.sleep(3)\n",
    "    print(time.time()-start)\n",
    "func()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.007540225982666\n"
     ]
    }
   ],
   "source": [
    "func()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'func'"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "func.__name__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "#封装出专门测试函数运行时间的函数\n",
    "def timer(func):\n",
    "    '''prints function time'''\n",
    "    start=time.time()\n",
    "    func()\n",
    "    print('function:{} run time is {}s'.format(func.__name__,time.time()-start))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f1 2\n",
      "f2\n",
      "f3\n",
      "function:f1 run time is 0.0s\n"
     ]
    }
   ],
   "source": [
    "timer(f1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f1 2\n",
      "f2\n",
      "f3\n",
      "function:f1 run time is 0.0\n"
     ]
    }
   ],
   "source": [
    "timer(f1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ff():\n",
    "    time.sleep(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "function:ff run time is 1.0030267238616943s\n"
     ]
    }
   ],
   "source": [
    "timer(ff)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
